(function($) {
	$.jsontotable = function(data, options) {
		options = $.extend({
			id: null, // target element id
			header: true,
			className: null,
			smartTable: true
		}, options);

		var obj = data;
		if (typeof obj === "string") {
			obj = $.parseJSON(obj);
		}

		if (options.id && obj.length) {

			var i, row;
			var table = $("<table></table>");

			if (options.className) {
				table.addClass(options.className);
			}
			var smartTableData = [];
			var splitChar = '::';

			$.fn.appendTr = function(rowData, isHeader, rowNum) {
				var frameTag = isHeader ? "thead" : "tbody";
				var rowTag = isHeader ? "th" : "td";
				var cellObj, cell;

				if (isHeader) {
					var thead = $("<" + frameTag + "></" + frameTag + ">");
					var emptyCell = $("<" + rowTag + "></" + rowTag + ">");
					var rowArr = [];
					builderMoreHeader(rowData, rowArr, emptyCell, 0);
					//反转
					rowArr.reverse();
					for (i in rowArr) {
						var rows = rowArr[i];
						var row = $("<tr></tr>");
						var data = [];
						for (j in rows) {
							var tmpCell = rows[j];
							row.append(tmpCell);
							var text = tmpCell.text();

							if (options.smartTable) { // 为 smarttable 数据
								var rowSpan = tmpCell.attr('rowspan');
								var colSpan = tmpCell.attr('colspan');
								rowSpan = rowSpan ? rowSpan : 0;
								colSpan = colSpan ? colSpan : 0;
								data.push(text + splitChar + rowSpan + splitChar + colSpan);
							}
						}
						if (options.smartTable) {
							smartTableData.push(data);
						}
						thead.append(row);
					}
					$(this).append(thead);
				} else {
					var row = $("<tr></tr>");
					var startCode = 1;
					var keyIndex = options.header ? rowNum : rowNum + 1;
					var prefix = '';
					var prefixIndex = 0;
					var data = [];
					for (key in rowData) {
						var point = String.fromCharCode(64 + startCode);
						var titlePoint = " id='" + (prefix + point + keyIndex) + "' title='" + (prefix + point + keyIndex) + "'";
						cellObj = rowData[key];
						if (typeof cellObj !== "function") {
							var value = " value='" + cellObj + "'";
							titlePoint += value;
							cell = "<" + rowTag + (options.excel ? titlePoint : "") + ">" + cellObj + "</" + rowTag + ">";
							row.append(cell);
							if (options.smartTable)
								data.push(cellObj + splitChar + '0' + splitChar + '0');
						}
						startCode++;

						if ((startCode - 1) % 26 == 0) {
							prefixIndex++;
							startCode = 1;
						}
						if (prefixIndex > 0) {
							prefix = String.fromCharCode(64 + prefixIndex);
						}
					}
					if (options.smartTable)
						smartTableData.push(data);

					var tbody = $(this).find("tbody");
					if (tbody.length === 0) {
						tbody = $(this).append("<tbody></tbody>");
					}
					tbody.append(row);
				}

				return this;
			};

			function builderMoreHeader(rowsData, rowArr, emptyCell, rowNum) {
				var isDone = true;
				var cellArr = [];
				var cellTextArr = [];
				var rmEleIndex = [];
				for (i in rowsData) {
					var emptyCellCopy = emptyCell.clone();
					rows = rowsData[i];
					if (rows.length > 0) {
						var lastCellText = rows.pop();
						if (cellTextArr[cellTextArr.length - 1] != lastCellText) {
							cellTextArr.push(lastCellText);
							emptyCellCopy.text(lastCellText);
							cellArr[i] = emptyCellCopy;
						} else {
							var tempCell = cellArr.pop();
							var colspan = tempCell.attr('colspan');
							colspan = !colspan ? 2 : parseInt(colspan) + 1
							tempCell.attr('colspan', colspan);
							cellArr.push(tempCell);
						}

						if (rows.length > 0) isDone = false;
						rowsData[i] = rows;
					} else {
						rmEleIndex.push(i);
						var cell = rowArr[rowNum - 1][i];
						var rowspan = cell.attr('rowspan');
						rowspan = !rowspan ? 2 : parseInt(rowspan) + 1
						cell.attr('rowspan', rowspan);
						cellArr[i] = cell;
					}
				}
				if (rmEleIndex.length > 0) {
					var add = 0;
					for (key in rmEleIndex) {
						var index = rmEleIndex[key];
						rowArr[rowNum - 1].splice(index - add, 1);
						add++;
					}
				}
				rowArr[rowNum++] = cellArr;
				if (!isDone) {
					builderMoreHeader(rowsData, rowArr, emptyCell, rowNum);
				}
			};

			if (options.header) {
				var rowData = obj[0];
				var rowDataStr = rowData.join('`');				
				rowData = rowDataStr.split('`');
				var headerData = [];
				for (key in rowData) {
					var rowStr = rowData[key];
					headerData[key] = rowStr.split('|');
				}

				table.appendTr(headerData, true);
			}
			for (i = options.header ? 1 : 0; i < obj.length; i++) {
				table.appendTr(obj[i], false, i);
			}
			if (options.smartTable) {
				table.data('tableJson', smartTableData);
			}
			$(options.id).append(table);
		}

		return this;
	};
}(jQuery));